package cn.blackbirds.blocks.layer;

import java.util.ArrayList;
import java.util.List;

import android.view.MotionEvent;

import cn.blackbirds.blocks.Globals;
import cn.blackbirds.blocks.MainActivity;
import cn.blackbirds.blocks.OpenFeintLeaderboard;
import cn.blackbirds.blocks.R;
import cn.blackbirds.blocks.Utils;
import cn.blackbirds.blocks.model.Block;
import cn.blackbirds.blocks.model.GameMap;
import cn.blackbirds.blocks.model.ParticleExplosion;

import com.wiyun.engine.actions.Action.Callback;
import com.wiyun.engine.actions.FadeOut;
import com.wiyun.engine.actions.IntervalAction;
import com.wiyun.engine.actions.MoveTo;
import com.wiyun.engine.astar.AStarStep;
import com.wiyun.engine.nodes.AtlasLabel;
import com.wiyun.engine.nodes.CharMap;
import com.wiyun.engine.nodes.Director;
import com.wiyun.engine.nodes.Label;
import com.wiyun.engine.nodes.Layer;
import com.wiyun.engine.nodes.Sprite;
import com.wiyun.engine.nodes.TiledSprite;
import com.wiyun.engine.opengl.Texture2D;
import com.wiyun.engine.particle.ParticleSystem;
import com.wiyun.engine.types.WYPoint;
import com.wiyun.engine.types.WYRect;
import com.wiyun.engine.utils.TargetSelector;

/**
 * 游戏主体
 * 
 * @author jang
 * 
 */
public class GameLayer extends Layer {
	
	public static int score = 0;
	Label scoreText;
	Label scoreNum;

	// 被选中的棋子
	Block preSelected;
	Block interchangeBlock;

	// 方块当前移动状态
	boolean isMoving;

	// 起点
	float moveX1;
	float moveY1;

	// 终点
	float moveX2;
	float moveY2;

	private GameMap map;

	AtlasLabel labelOnce; 
	// 移动轨迹
	ArrayList<AStarStep> movePath;
	
	private ParticleSystem emitter;
	
	AtlasLabel labelGe;
	AtlasLabel labelShi;
	AtlasLabel labelBai;
	AtlasLabel labelQian;
	AtlasLabel labelWan;
	AtlasLabel labelShiWan;
	AtlasLabel labelBaiWan;
	
	int scoreGe = 0;
	int scoreShi = 0;
	int scoreBai = 0;
	int scoreQian = 0;
	int scoreWan = 0;
	int scoreShiWan = 0;
	int scoreBaiWan = 0;
	private MainActivity mainActive;
	public GameLayer(MainActivity mainActive) {
		this.mainActive =  mainActive;
		initView();

		initScore();

		// 初始化棋子
		makeRandomBlock(Globals.INITIAL_BLOCKS);

		setTouchEnabled(true);
		
		Globals.onStopBg();
	}

	/**
	 * 初始化棋盘
	 */
	private void initView() {				
		TiledSprite	mTS = TiledSprite.make(Texture2D.makePNG(R.drawable.map));		
		mTS.setTileDirection(false, false); // 可以设置平铺的方向, 缺省就是x, y方向都平铺S
		addChild(mTS);				
		mTS.autoRelease();	

		map = new GameMap();
		map.bindingView(this);
	}

	private void initScore() {
		drawScore();
		showScore();
	}

	/**
	 * 随机生成棋子，并布局到棋盘中任意位置
	 * 
	 * @param blocks
	 */
	private void makeRandomBlock(int blocks) {

		for (int i = 0; i < blocks && !map.isFull(); i++) {
			int x;
			int y;

			do {
				x = Utils.makeRandom(Globals.MAP_COLS);
				y = Utils.makeRandom(Globals.MAP_ROWS);
			} while (map.isBlockedAt(x, y));

			// 生成一个随机数，根据随机数生成相应的图形
			int random = Utils.makeRandom(6);
			map.setBlock(x, y, Block.make(random));

			// 生成新棋子时判断周围是否满足消失条件
			float[] xy = GameMap.convertToPositionFloat(x, y);
			
			removeRandomNearByBlocks(xy[0], xy[1]);					
		}
		
		//判断游戏是否结束
		if(map.isFull())
		{
			Globals.playGameover();
			GameOverLayer gameOverLayer = new GameOverLayer(String.format("%d", score), mainActive, this);	
			setTouchEnabled(false);
			addChild(gameOverLayer);
			autoRelease();							
		}
		
	}

	@Override
	public boolean wyTouchesEnded(MotionEvent event) {
		if (isMoving) {
			return true;
		}

		WYPoint e = Director.getInstance().convertToGL(event.getX(), event.getY());
		if (!GameMap.isInner(e.x, e.y)) {
			return true;
		}
		Block curSelected = map.getBlock(e.x, e.y);

		/*** 选择方块进行移动 **/
		if (curSelected != null) {

			if (preSelected != null) {
				preSelected.reset();

				// 两次选择同一颗棋子
				if (curSelected == preSelected) {
					
					preSelected = curSelected;
					preSelected.sparkle();

					// 起点
					moveX1 = e.x;
					moveY1 = e.y;

					return true;
				}
			}

			preSelected = curSelected;
			preSelected.sparkle();

			// 起点
			moveX1 = e.x;
			moveY1 = e.y;

			return true;
		}

		// 终点
		moveX2 = e.x;
		moveY2 = e.y;

		//第一次没有选择棋子，将不移动
		if(preSelected != null){
			// 开始移动棋子
			moveByPath();
		}
		

		return false;
	}

	/**
	 * 沿指定路径移动棋子
	 */
	private void moveByPath() {
		isMoving = false;

		preSelected.reset();

		// 找出两点间的路径，是否最近？待确认
		movePath = map.findPath(moveX1, moveY1, moveX2, moveY2);

		if (movePath != null && !movePath.isEmpty()) {
			isMoving = true;
			moveToNext();
		}
	}

	MoveTo move;

	private void moveToNext() {
		if (movePath.isEmpty()) {
			return;
		}
		
		Globals.playMove();

		AStarStep step = movePath.get(movePath.size() - 1);
		move = map.findMoveTo(preSelected, step);

		move.setCallback(callback);
		preSelected.runAction(move);

		movePath.remove(movePath.size() - 1);
	}

	Callback callback = new Callback() {
		public void onStart(int actionPointer) {

		}

		public void onStop(int actionPointer) {


			if (isArrived()) {
				isMoving = false;

				preSelected.stopAllActions();

				map.removeBlock(moveX1, moveY1);

				map.setBlock(moveX2, moveY2, preSelected);
				preSelected = null;

				removeNearBy(moveX2, moveY2);

			} else {
				moveToNext();
			}

		}

		public void onUpdate(int actionPointer, float t) {
		}
	};

	private boolean isArrived() {
		return movePath.isEmpty() ? true : false;
	}

	/**
	 * 连续的棋子消失
	 * 
	 * @param x
	 * @param y
	 */
	private void removeNearBy(float x, float y) {

		List<Block> list = map.findNearBy(x, y);

		if (list != null && list.size() >= Globals.CONTINUOUS_BLOCKS) {

			for (Block each : list) {
				map.removeBlock(each);						
				drawParticleExplosion(each.getPositionX(), each.getPositionY());
			}
			
			Globals.playRemove();

			score += Utils.getScoreThisTunr(list);
			//显示每次得分
			showOnceScore(x, y, Utils.getScoreThisTunr(list));
			//重新显示得分
			showScore();
		} else {
			makeRandomBlock(Globals.RECREATE_BLOCKS);
		}
	}
	
	/**
	 * 消除随机生成时产生的相连棋子
	 * @param x
	 * @param y
	 */
	private void removeRandomNearByBlocks(float x, float y){
		List<Block> list = map.findNearBy(x, y);

		if (list != null && list.size() >= Globals.CONTINUOUS_BLOCKS) {

			for (Block each : list) {

				map.removeBlock(each);
				
				drawParticleExplosion(each.getPositionX(), each.getPositionY());
			}
			
			Globals.playRemove();
			
			score += Utils.getScoreThisTunr(list);
			
			//显示每次得分
			showOnceScore(x, y, Utils.getScoreThisTunr(list));
			//显示总得分
			showScore();
		}
	}
	
	/*
	 * 绘制粒子效果
	 * 
	 */
	private void drawParticleExplosion(float x, float y){
		// create particle system
		emitter = ParticleExplosion.make();
		addChild(emitter);
		emitter.setPosition(x, y);
	}
	
	/**
	 * 绘制得分
	 */
	private void drawScore(){
		Sprite sprite = Sprite.make(R.drawable.score_text);
        sprite.autoRelease();   
        addChild(sprite);
        sprite.setPosition(70, 748);
	}
	
	/**
	 * 显示每次的得分
	 * @param dt
	 */
	private void showOnceScore(float x, float y, int score){		
		// create charmap
    	CharMap map1 = CharMap.make();
    	map1.autoRelease();
    	float width = 28;
    	float height = 40;
		map1.mapChar(WYRect.make(0, 0, width, height), '0');
		map1.mapChar(WYRect.make(width, 0, width, height), '1');
		map1.mapChar(WYRect.make(width*2, 0, width, height), '2');
		map1.mapChar(WYRect.make(width*3, 0, width, height), '3');
		map1.mapChar(WYRect.make(width*4, 0, width, height), '4');
		map1.mapChar(WYRect.make(width*5, 0, width, height), '5');
		map1.mapChar(WYRect.make(width*6, 0, width, height), '6');
		map1.mapChar(WYRect.make(width*7, 0, width, height), '7');
		map1.mapChar(WYRect.make(width*8, 0, width, height), '8');
		map1.mapChar(WYRect.make(width*9, 0, width, height), '9');
		map1.mapChar(WYRect.make(width*10, 0, width, height), '+');
    	
    	Texture2D texture1 = Texture2D.makePNG(R.drawable.click_score);	    	
    	labelOnce = AtlasLabel.make("1", texture1, map1);       
    	labelOnce.setPosition(x, y);
        addChild(labelOnce);
        autoRelease();
        labelOnce.setText(String.format("+%d", score));  
        IntervalAction a = (IntervalAction)FadeOut.make(1).autoRelease();
        labelOnce.runAction(a);
        
	}
	
	/**
	 * 显示分数
	 */
	private void showScore(){		
		// create charmap
    	CharMap map = CharMap.make();
    	map.autoRelease();
    	float width = 24;
    	float height = 30;
		map.mapChar(WYRect.make(0, 0, width, height), '0');
		map.mapChar(WYRect.make(width, 0, width, height), '1');
		map.mapChar(WYRect.make(width*2, 0, width, height), '2');
		map.mapChar(WYRect.make(width*3, 0, width, height), '3');
		map.mapChar(WYRect.make(width*4, 0, width, height), '4');
		map.mapChar(WYRect.make(width*5, 0, width, height), '5');
		map.mapChar(WYRect.make(width*6, 0, width, height), '6');
		map.mapChar(WYRect.make(width*7, 0, width, height), '7');
		map.mapChar(WYRect.make(width*8, 0, width, height), '8');
		map.mapChar(WYRect.make(width*9, 0, width, height), '9');
    	    	
    	Texture2D texture = Texture2D.makePNG(R.drawable.score);	 
    	
    	float scroeY = 730;
    	float scoreX = 100;
    	
    	if(labelGe!=null)
    		removeChild(labelGe, true);
    	//个位 
    	labelGe = AtlasLabel.make("0", texture, map);
    	labelGe.setAnchorPercent(0, 0);
    	labelGe.setPosition(scoreX+width*6, scroeY);
        addChild(labelGe);
    	
        if(labelShi!=null)
        	removeChild(labelShi, true);
        //十位  
        labelShi = AtlasLabel.make("0", texture, map);
        labelShi.setAnchorPercent(0, 0);
        labelShi.setPosition(scoreX+width*5, scroeY);
        addChild(labelShi);
    	
        if(labelBai!=null)
        	removeChild(labelBai, true);
        //百位
        labelBai = AtlasLabel.make("0", texture, map);
        labelBai.setAnchorPercent(0, 0);
        labelBai.setPosition(scoreX+width*4, scroeY);
        addChild(labelBai);
    	    	    	    	
        if(labelQian!=null)
        	removeChild(labelQian, true);
        //千位
        labelQian = AtlasLabel.make("0", texture, map);
        labelQian.setAnchorPercent(0, 0);
        labelQian.setPosition(scoreX+width*3, scroeY);
        addChild(labelQian);
        
        if(labelWan!=null)
        	removeChild(labelWan, true);
        //万位
        labelWan = AtlasLabel.make("0", texture, map);
        labelWan.setAnchorPercent(0, 0);
        labelWan.setPosition(scoreX+width*2, scroeY);
        addChild(labelWan);
        
        if(labelShiWan!=null)
        	removeChild(labelShiWan, true);
        //十万位
        labelShiWan = AtlasLabel.make("0", texture, map);
        labelShiWan.setAnchorPercent(0, 0);
        labelShiWan.setPosition(scoreX+width*1, scroeY);
        addChild(labelShiWan);               
        
        schedule(new TargetSelector(this, "step(float)", new Object[] { 0f }), 0f);        
	}			
	
	/**
	 * 滚动位数
	 * @param dt
	 */
	public void step(float dt) {	
		
		//个位
		if(scoreGe < gerLabNum(score, 1)){
			scoreGe++;                           
        }else if(scoreGe > gerLabNum(score, 1)){
        	scoreGe++;
        	scoreGe = gerLabNum(scoreGe, 1);
        }
		labelGe.setText(String.format("%d", scoreGe)); 
		
		//十位
		if(scoreShi < gerLabNum(score, 10)){
			scoreShi++;                           
        }else if(scoreShi > gerLabNum(score, 10)){
        	scoreShi++;
        	scoreShi = gerLabNum(scoreShi, 1);
        }
		labelShi.setText(String.format("%d", scoreShi)); 
		
		//百位
		if(scoreBai < gerLabNum(score, 100)){
			scoreBai++;                           
        }else if(scoreBai > gerLabNum(score, 100)){
        	scoreBai++;
        	scoreBai = gerLabNum(scoreBai, 1);
        }
		labelBai.setText(String.format("%d", scoreBai));
		
		//千位
		if(scoreQian < gerLabNum(score, 1000)){
			scoreQian++;                           
        }else if(scoreQian > gerLabNum(score, 1000)){
        	scoreQian++;
        	scoreQian = gerLabNum(scoreQian, 1);
        }
		labelQian.setText(String.format("%d", scoreQian));
		
        //万位
		if(scoreWan < gerLabNum(score, 10000)){
			scoreWan++;                           
        }else if(scoreWan > gerLabNum(score, 10000)){
        	scoreWan++;
        	scoreWan = gerLabNum(scoreWan, 1);
        }
		labelWan.setText(String.format("%d", scoreWan));
		
        //十万位
		if(scoreShiWan < gerLabNum(score, 100000)){
			scoreShiWan++;                           
        }else if(scoreShiWan > gerLabNum(score, 100000)){
        	scoreShiWan++;
        	scoreShiWan = gerLabNum(scoreShiWan, 1);
        }
		labelShiWan.setText(String.format("%d", scoreShiWan));		     
		
    }		
	
	/**
	 * 获得某位的数字
	 * @param zongfen 总分数
	 * @param weishu 位数 1个  10十 100百 1000千
	 * @return
	 */
	public int gerLabNum(int zongfen, int weishu){
		int result = zongfen%(weishu*10)/weishu;
		return result;
	}
	
	public void gameover(){
		mainActive.runOnUiThread(new Runnable() {
			public void run() {
				//send score to openfeint
				OpenFeintLeaderboard openFeintLeaderboard = new OpenFeintLeaderboard();
				openFeintLeaderboard.sendScore(score);		
				score = 0;
			}
		});			
	}
}
